# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from sqlalchemy.orm import mapper
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, backref
from sqlalchemy import ForeignKey
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Table, Column, Integer, String, Boolean, Float, DateTime, MetaData, ForeignKey
import datetime

# Initializing database :
testDatabasePath = ":memory:" # used for test 
databasePath = "base.sqlite" # used for production
engine = create_engine('sqlite:///' + databasePath, echo=False)

# setting up root class for declarative declaration
Base = declarative_base(bind=engine)

class Asset(Base):
	__tablename__ = 'asset'
	
	id = Column(Integer, primary_key=True)
	name = Column(String(255))
	ticker_symbol = Column(String(50))
	
	def __init__(self, name, ticker_symbol = None):
		self.name = name
		self.ticker_symbol = ticker_symbol
		
	def __repr__(self):
		return "<Asset('%s','%s')>" % (self.name, self.ticker_symbol)
		
class ExchangePlace(Base):
	__tablename__ = 'exchange_place'
	
	id = Column(Integer, primary_key=True)
	name = Column(String(255))
	
	def __init__(self, name):
		self.name = name
		
	def __repr__(self):
		return "<ExchangePlace('%s')>" % (self.name)
	
	
class Broker(Base):
	__tablename__ = 'broker'
	
	id = Column(Integer, primary_key=True)
	name = Column(String(255))
	fees = Column(Float)
	is_percentage = Column(Boolean)
	
	def __init__(self, name, fees, is_percentage=False):
		self.name = name
		self.fees = fees
		self.is_percentage = is_percentage
		
	def __repr__(self):
		return "<Broker('%s,%d,%b')>" % (self.name, self.fees, self.is_percentage)


class Position(Base):
	__tablename__ = 'position'
	
	id = Column('id', Integer, primary_key=True)
	asset_id = Column(Integer, ForeignKey('asset.id'))
	asset = relation(Asset, backref=backref('position', order_by=id))
	broker_id = Column(Integer, ForeignKey('broker.id'))
	broker = relation(Broker, backref=backref('position', order_by=id))
	create_date = Column(DateTime, default=datetime.datetime.utcnow)
	start_date = Column(DateTime)
	start_price = Column(Float)
	end_date = Column(DateTime)
	end_price = Column(Float)
	
	
	def __init__(self, asset, broker, start_date, start_price):
		self.asset = asset
		self.broker = broker
		# we are dealing with string like 'dd/MM/yyyy'
		date_components = start_date.split('/')
		date_components.reverse()
		self.start_date = datetime.datetime(int(date_components[0]), 
		int(date_components[1]),
		int(date_components[2]))
		self.start_price = start_price
		
	def __repr__(self):
		return "<Position('%s','%s','%s')>" % (self.asset, self.broker, self.create_date)

class HistoryPrice(Base):
	__tablename__ = 'history_price'

	id = Column('id', Integer, primary_key=True)
	asset_id = Column(Integer, ForeignKey('asset.id'))
	asset = relation(Asset, backref=backref('history_price', order_by=id))
	price_date = Column(DateTime)
	open_price = Column(Float)
	high_price = Column(Float)
	low_price = Column(Float)
	close_price = Column(Float)


	def __init__(self, asset, price_date, open_price, high_price, low_price, close_price):
		self.asset = asset
		# we are dealing with string like 'dd/MM/yyyy'
		date_components = price_date.split('/')
		date_components.reverse()
		self.price_date = datetime.datetime(int(date_components[0]), 
		int(date_components[1]),
		int(date_components[2]))
		self.open_price = open_price
		self.high_price = high_price
		self.low_price = low_price
		self.close_price = close_price

	def __repr__(self):
		return "<HistoryPrice('%s','%s','%s','%s','%s','%s')>" % (self.asset, self.price_date, 
			self.open_price, self.high_price, self.low_price, self.close_price)


Base.metadata.create_all(engine)

# initializing session :
Session = sessionmaker(bind=engine)
session = Session()
# total = Asset("Total")
# broker = Broker("SGAM", 50, True)
# positionMerdique = Position(total, broker, "26/12/1986", 30)
# session.add(positionMerdique)
# session.commit()

if __name__ == "__main__":
	""" testing introspection with python's sqlalchemy objects """
	
	def info(object, spacing=10, collapse=1):
		"""Print methods and doc strings.
		Takes module, class, list, dictionary, or string."""
		methodList = [method for method in dir(object)]
		processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
		print ("\n".join(["%s %s" %
						  (method.ljust(spacing),
						   processFunc(str(getattr(object, method).__doc__)))
						 for method in methodList]))
	
	info(Asset)
	
"""
>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=engine)
>>> session = Session()
>>> veolia_Asset = Asset('Veolia')
>>> session.add(veolia_Asset)
>>> our_user = session.query(Asset).filter_by(name='Veolia').first()
"""

